package cn.gem.rainbow.cfg.aop;

import lombok.extern.log4j.Log4j2;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * 切片的实现需要注意@Aspect,@Component以及@Around这三个注解的使用，详细查看官方文档：
 * https://cloud.tencent.com/developer/article/1591186
 * https://docs.spring.io/spring/docs/5.0.12.RELEASE/spring-framework-reference/core.html#aop
 *
 * https://www.jb51.net/article/113683.htm
 *
 * 多个切片存在是，Order越小越先执行
 * 执行顺序为  1进->2进->2出->1出
 */
@Aspect
@Order(1) // 控制多个Aspect的执行顺序，越小越先执行
@Component
@Log4j2
public class ReqAspect {



    //环绕通知
    //切面为cn.gem.rainbow.api包下的类
    @Around("execution(* cn.gem.rainbow.api.*.*(..))")
    public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("*********AOP start******* order=1 *************************");
        log.warn("切片开始。。。");
        long startTime = System.currentTimeMillis();

        // 获取请求入参
        Object[] args = proceedingJoinPoint.getArgs();
        Arrays.stream(args).forEach(arg -> log.info("arg is {}", arg));

        // 获取相应
        Object response = proceedingJoinPoint.proceed();

        long endTime = System.currentTimeMillis();
        log.info("请求目标类:{}, 耗时{}ms", proceedingJoinPoint.getSignature(), (endTime - startTime));
        log.warn("切片结束。。。");
        System.out.println("*******AOP end**********************************");

        return response;
    }

}
